package br.eng.eliseu.gwt.gestaoWeb.server.service;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import br.eng.eliseu.gwt.gestaoWeb.client.service.LoginService;
import br.eng.eliseu.gwt.gestaoWeb.model.UsuarioAutenticadoVO;
import br.eng.eliseu.gwt.gestaoWeb.model.empresa.Empresa;
import br.eng.eliseu.gwt.gestaoWeb.model.empresa.EmpresaSistema;
import br.eng.eliseu.gwt.gestaoWeb.model.enums.SistemasEnum;
import br.eng.eliseu.gwt.gestaoWeb.model.enums.StatusEnum;
import br.eng.eliseu.gwt.gestaoWeb.model.usuario.DireitoUsuarioEnum;
import br.eng.eliseu.gwt.gestaoWeb.model.usuario.Usuario;
import br.eng.eliseu.gwt.gestaoWeb.model.usuario.UsuarioAcesso;
import br.eng.eliseu.gwt.gestaoWeb.model.usuario.UsuarioSistema;
import br.eng.eliseu.gwt.gestaoWeb.server.command.generico.GetEntityListCommand;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

@Singleton
public class LoginServiceImpl extends RemoteServiceServlet implements LoginService{

	private static final long serialVersionUID = -2164339367091650949L;

	public LoginServiceImpl() {	}
	
	@Inject Injector injector;

	private GetEntityListCommand cmd;
	
	@SuppressWarnings("unchecked")
	public Usuario autenticaUsuario(String nomeUsuario) throws Exception {
		
		Usuario usuario;
		
		/* Pega e entidade Usuario
		 */
		String n = nomeUsuario.toUpperCase().trim().replaceAll(" ", "_");
		cmd = injector.getInstance(GetEntityListCommand.class);
		cmd.setNamedQuery("usuario.porNome");
		cmd.addParameter("nome", n);
		List<Usuario> lUsuario = cmd.call();
		if(lUsuario.size()>0){
			usuario = lUsuario.get(0);
		} else {
			throw new Exception("Não existe este usuario cadastrado");
		}
		return usuario;
	}

	
	@SuppressWarnings("unchecked")
	public List<UsuarioSistema> autenticaUsuario(String nomeUsuario, String senha) throws Exception {

		Usuario usuario = autenticaUsuario(nomeUsuario);
		
		if (!senha.equals(usuario.getSenha())){
			throw new Exception("A senha do usuario não esta correta");
		}
		
		/* Pega e entidade UsuarioSistema
		 */
		cmd = injector.getInstance(GetEntityListCommand.class);
		cmd.setNamedQuery("usuarioSistema.porUsuario");
		cmd.addParameter("usuario", usuario);
		List<UsuarioSistema> lUsuarioSistema = cmd.call();
		if(lUsuarioSistema.size()<=0){
			throw new Exception("Este Usuário não esta habilitada a usar os sistemas.");
		}

		return lUsuarioSistema;
	}


	@SuppressWarnings("unchecked")
	public UsuarioAutenticadoVO autenticaUsuario(Empresa empresa, SistemasEnum sistema, Usuario usuario)throws Exception {
		
		EmpresaSistema empresaSistema = null;
		UsuarioSistema usuarioSistema = null;


		/* Pega e entidade EmpresaSistema
		 */
		cmd = injector.getInstance(GetEntityListCommand.class);
		cmd.setNamedQuery("empresaSistema.porEmpresaSistema");
		cmd.addParameter("empresa", empresa);
		cmd.addParameter("sistema", sistema);
		cmd.setMaxResults(1);
		List<EmpresaSistema> lEmpresaSistema = cmd.call();
		if(lEmpresaSistema.size()>0){
			empresaSistema = lEmpresaSistema.get(0);
		} else {
			throw new Exception("Esta empresa não esta habilitada a usar o sistema "+sistema.getNome());
		}

		if (empresaSistema.getStatus().equals(StatusEnum.INTATIVO) || empresaSistema.getDtFim()!=null){
			throw new Exception("A conta do sistema "+sistema.getNome()+" esta DESATIVADA.");
		}
		
		/* Pega e entidade UsuarioSistema
		 */
		cmd = injector.getInstance(GetEntityListCommand.class);
		cmd.setNamedQuery("usuarioSistema.porUsuarioSistema");
		cmd.addParameter("usuario", usuario);
		cmd.addParameter("empresaSistema", empresaSistema);
		cmd.setMaxResults(1);
		List<UsuarioSistema> lUsuarioSistema = cmd.call();
		if(lUsuarioSistema.size()>0){
			usuarioSistema = lUsuarioSistema.get(0);
		} else {
			throw new Exception("Este Usuário não esta habilitada a usar o sistema "+sistema.getNome());
		}

		if (usuarioSistema.getStatus().equals(StatusEnum.INTATIVO) || usuarioSistema.getDtFim()!=null){
			throw new Exception("A conta do sistema "+sistema.getNome()+" esta DESATIVADA para este usuário.");
		}
		
		UsuarioAutenticadoVO usrAutenticado = new UsuarioAutenticadoVO();
		usrAutenticado.setUsuarioAutenticado(usuarioSistema);
		if (usuarioSistema.getDireito().compareTo(DireitoUsuarioEnum.DONO)>0){
			/* O usuario com direito baixo
			 */
			cmd = injector.getInstance(GetEntityListCommand.class);
			cmd.setNamedQuery("usuarioAcesso.porUsuarioSistema");
			cmd.addParameter("usuarioSistema", usuarioSistema);
			cmd.setMaxResults(1);
			List<UsuarioAcesso> lUsuarioAcesso = cmd.call();
			if(lUsuarioAcesso.size()>0){
				usrAutenticado.setAcesso(lUsuarioAcesso);
			} else {
				throw new Exception("Usuarios com deireito de "+usuarioSistema.getDireito().getNome()+" precisa ter direitos de tela definidos");
			}
		}
		
		autenticaUsuario(usrAutenticado);
		
		return usrAutenticado;
	}

	private void autenticaUsuario(UsuarioAutenticadoVO user) {
		HttpServletRequest req = getThreadLocalRequest();
		HttpSession session = req.getSession();
		session.setAttribute("usuario", user);
	}
	
	
	public void desconecta() throws Exception {
		HttpServletRequest req = getThreadLocalRequest();
		HttpSession session = req.getSession();
		if(session != null) {
			session.setAttribute("usuario", null);
		}
		getThreadLocalRequest().getSession(true).invalidate();
		
	}
	
	public UsuarioAutenticadoVO getUsuarioAutenticado() throws Exception {
		HttpServletRequest req = getThreadLocalRequest();
		HttpSession session = req.getSession();
		UsuarioAutenticadoVO user = null;
		if(session != null) {
			user = (UsuarioAutenticadoVO) session.getAttribute("usuario");
		} else {
			throw new Exception("Sessão não encontrada (Usuário não autentidado).");
		}
		return user;
	}


}
